<template>
  <div class="report-edit-container">
    <!-- 自定义加载动画 -->
    <div v-if="pageLoading" class="custom-loading-container">
      <div class="loading-backdrop"></div>
      <div class="loading-content">
        <div class="loading-animation">
          <svg viewBox="0 0 100 100">
            <circle cx="50" cy="50" r="45" fill="none" stroke="#f0f2f5" stroke-width="8"></circle>
            <circle
              class="progress-circle"
              cx="50"
              cy="50"
              r="45"
              fill="none"
              stroke-width="8"
            ></circle>
          </svg>
          <span class="document-icon">
            <el-icon :size="32"><Document /></el-icon>
          </span>
          <div class="star star1"></div>
          <div class="star star2"></div>
          <div class="star star3"></div>
          <div class="star star4"></div>
        </div>
        <div class="loading-text">
          <h3>正在生成章节内容</h3>
          <p>请稍候，我们正在为您生成分析报告章节内容</p>
          <div class="loading-dots">
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
          </div>
        </div>
        <div class="loading-progress-status">
          <div class="progress-item">
            <span class="label">总计</span>
            <span class="value">{{ progressInfo.total }}</span>
          </div>
          <div class="progress-item success">
            <el-icon><Check /></el-icon>
            <span class="label">已完成</span>
            <span class="value">{{ progressInfo.completed }}</span>
          </div>
          <div class="progress-item error">
            <el-icon><Close /></el-icon>
            <span class="label">失败</span>
            <span class="value">{{ progressInfo.failed }}</span>
          </div>
        </div>
      </div>
    </div>
    <div class="content-tabs-header">
      <el-tabs v-model="activeTab" type="card" class="content-tabs">
        <el-tab-pane label="报告编辑" name="reportedit"></el-tab-pane>
      </el-tabs>
    </div>
    <div class="report-header glass-card">
      <div class="title-section">
        <div class="report-icon">
          <el-icon><Document /></el-icon>
        </div>
        <div class="title-content">
          <h2 class="section-title">
            {{ reportTitle }}
            <el-tooltip content="编辑报表信息" placement="top" effect="light">
              <i class="edit-icon" @click="showReportInfoDialog">
                <el-icon><EditPen /></el-icon>
              </i>
            </el-tooltip>
          </h2>
          <p class="section-description">{{ reportRequirements }}</p>
        </div>
      </div>
      <div class="header-actions">
        <el-button
          type="primary"
          size="large"
          class="preview-button"
          @click="openReportDisplayPage"
        >
          <el-icon :size="18"><View /></el-icon> 预览报告
        </el-button>

        <el-button
          type="warning"
          size="large"
          @click="showDataRangeDialog"
          class="data-range-button"
        >
          <el-icon :size="18"><Filter /></el-icon> 修改数据范围
        </el-button>

        <el-button
          type="success"
          style="display: none"
          @click="generateOutline"
          :loading="generatingOutlineStatus"
          class="premium-button generate-button"
        >
          <el-icon><Refresh /></el-icon> 生成分析大纲
        </el-button>
      </div>
    </div>

    <!-- 报告编辑与展示阶段 - 左右布局 -->
    <div class="report-stage">
      <div class="report-layout">
        <!-- 左侧大纲树 -->
        <div class="outline-panel glass-card">
          <div class="outline-header">
            <div class="outline-title">
              <el-icon><List /></el-icon>
              <h3>分析报告大纲</h3>
            </div>
            <div class="outline-actions">
              <!-- 删除之前的生成选中章节按钮 -->
            </div>
          </div>

          <div class="outline-tree-container" v-loading="generatingOutline">
            <el-tree
              ref="outlineTree"
              :data="treeOutline"
              node-key="id"
              default-expand-all
              :expand-on-click-node="false"
              :highlight-current="true"
              @node-click="handleNodeClick"
              draggable
              :allow-drop="allowDrop"
              :allow-drag="allowDrag"
              @node-drag-end="handleDragEnd"
            >
              <template #default="{ data }">
                <div class="outline-node">
                  <!-- 移除勾选框 -->
                  <div class="outline-main-content">
                    <span v-if="data.isEditing">
                      <el-input
                        v-model="data.title"
                        size="small"
                        @blur="finishEditNode(data)"
                        @keyup.enter="finishEditNode(data)"
                        ref="nodeEditInput"
                      />
                    </span>
                    <el-tooltip
                      v-else
                      :content="data.content || '暂无内容描述'"
                      placement="right"
                      effect="light"
                      :enterable="false"
                      :show-after="300"
                      popper-class="node-tooltip"
                    >
                      <span class="outline-node-label">
                        {{ data.title }}
                        <i class="edit-icon" @click.stop="startEditNode(data)">
                          <el-icon><EditPen /></el-icon>
                        </i>
                        <!-- 添加删除按钮到编辑图标后面，仅在非父节点上显示 -->
                        <el-tooltip
                          v-if="!data.children"
                          content="删除章节"
                          placement="top"
                          effect="light"
                        >
                          <i class="delete-icon" @click.stop="deleteNode(data)">
                            <el-icon><Delete /></el-icon>
                          </i>
                        </el-tooltip>
                      </span>
                    </el-tooltip>
                  </div>
                  <div class="outline-right-section">
                    <span v-if="!data.children" class="node-status-icon">
                      <el-tag
                        v-if="data.status === 'completed'"
                        size="small"
                        effect="light"
                        type="success"
                        class="status-tag"
                      >
                        已生成
                      </el-tag>
                      <el-tag
                        v-else-if="data.status === 'in_progress'"
                        size="small"
                        effect="light"
                        type="warning"
                        class="status-tag"
                      >
                        生成中
                      </el-tag>
                      <el-tag
                        v-else-if="data.status === 'failed'"
                        size="small"
                        effect="light"
                        type="danger"
                        class="status-tag"
                      >
                        生成失败
                      </el-tag>
                      <el-tag v-else size="small" effect="light" type="info" class="status-tag">
                        待生成
                      </el-tag>
                    </span>
                    <!-- 删除旧位置的删除按钮 -->
                  </div>
                </div>
              </template>
            </el-tree>
          </div>

          <!-- 添加一键生成报告内容按钮 -->
          <div class="generate-all-button-container">
            <el-tooltip
              content="仅为没有内容的章节生成分析内容"
              placement="top"
              effect="light"
              :show-after="300"
            >
              <el-button
                type="primary"
                class="generate-all-button"
                @click="generateAllEmptySections"
                :loading="generatingAllSections"
                :disabled="generatingReport"
              >
                <el-icon><Connection /></el-icon> 一键生成报告章节内容
              </el-button>
            </el-tooltip>
            <el-tooltip
              content="清除所有章节的分析内容"
              placement="top"
              effect="light"
              :show-after="300"
            >
              <el-button
                type="danger"
                class="clear-all-button"
                @click="clearAllSections"
                :loading="clearingAllSections"
                :disabled="generatingReport"
              >
                <el-icon><Delete /></el-icon> 一键清除报告章节内容
              </el-button>
            </el-tooltip>
          </div>
        </div>

        <!-- 右侧内容区 -->
        <div class="content-panel">
          <div v-if="!selectedSection" class="content-empty">
            <el-empty description="请从左侧选择一个章节查看内容" :image-size="120"> </el-empty>
          </div>
          <div v-else class="section-content">
            <!-- 编辑模式 -->
            <div v-if="isEditingContent" class="section-editor-container glass-card">
              <div class="section-editor-header">
                <h3>{{ selectedSection.dimension_name }}</h3>
                <div class="editor-actions">
                  <el-button
                    type="primary"
                    size="small"
                    @click="saveAnalysisContent"
                    :loading="savingContent"
                  >
                    <el-icon><Check /></el-icon> 保存
                  </el-button>
                  <el-button type="default" size="small" @click="toggleEditMode">
                    <el-icon><View /></el-icon> 预览
                  </el-button>
                </div>
              </div>
              <div class="section-editor">
                <el-input
                  v-model="selectedSection.analysis_result"
                  type="textarea"
                  :rows="10"
                  placeholder="编辑章节内容..."
                  @input="updateSectionContent"
                />
              </div>
            </div>

            <!-- 预览模式（默认） -->
            <div v-else>
              <!-- 显示维度内容或空状态 -->
              <div class="section-preview glass-card">
                <div class="preview-header">
                  <h3>{{ selectedSection.dimension_name }}</h3>
                  <div class="preview-actions">
                    <el-tooltip content="编辑内容" placement="top">
                      <el-button type="primary" @click="toggleEditMode" circle size="small">
                        <el-icon><EditPen /></el-icon>
                      </el-button>
                    </el-tooltip>
                    <el-tooltip content="重新生成内容" placement="top">
                      <el-button
                        type="success"
                        @click="showUserOpinionDialog(selectedSection)"
                        :loading="generatingSectionContent"
                        circle
                        size="small"
                      >
                        <el-icon><Connection /></el-icon>
                      </el-button>
                    </el-tooltip>
                  </div>
                </div>
                <div
                  v-if="selectedSection.analysis_result"
                  class="preview-content"
                  v-html="renderedMarkdown(selectedSection.analysis_result)"
                ></div>
                <div v-else class="empty-analysis-container">
                  <div class="empty-analysis-content">
                    <el-empty
                      :image-size="100"
                      description="还没有分析内容"
                      class="empty-placeholder"
                    >
                      <div class="empty-description">
                        <p>该维度还没有生成分析内容，请再左侧使用AI生成详细分析</p>
                      </div>
                    </el-empty>
                    <div class="generate-action"></div>
                  </div>
                </div>

                <data-display-component
                  v-if="parsedJsonData"
                  :data="parsedJsonData"
                  :columns="jsonDataColumns"
                  :title="selectedSection.dimension_name"
                  :max-height="400"
                  :chart-height="350"
                  :loading="false"
                  default-mode="table"
                  :enable-export="true"
                  :enable-custom-config="true"
                  @export-data="handleDataExport"
                />
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 完整报告预览对话框 -->
      <el-dialog
        v-model="fullReportDialogVisible"
        title="完整分析报告预览"
        width="80%"
        top="5vh"
        :fullscreen="false"
      >
        <div class="full-report-container" v-loading="generatingReport">
          <div v-if="!fullReport" class="report-empty">
            <el-empty description="报告生成中..." :image-size="120">
              <template #description>
                <p>AI正在为您生成分析报告，请稍候...</p>
              </template>
            </el-empty>
          </div>
          <div v-else class="report-content glass-card">
            <div class="report-title">{{ reportTitle }}</div>
            <div class="report-body" v-html="renderedReport"></div>
          </div>
        </div>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="fullReportDialogVisible = false">关闭</el-button>
            <el-button type="success" @click="openReportDisplayPage">
              <el-icon><View /></el-icon> 在新窗口查看
            </el-button>
            <el-button type="primary" @click="handleExport('markdown')">
              <el-icon><Download /></el-icon> 导出为Markdown
            </el-button>
            <el-button type="primary" @click="handleExport('pdf')">
              <el-icon><Download /></el-icon> 导出为PDF
            </el-button>
          </span>
        </template>
      </el-dialog>

      <!-- 添加用户输入要求的对话框 -->
      <el-dialog
        v-model="userOpinionDialogVisible"
        title="输入生成要求"
        width="50%"
        :close-on-click-modal="false"
      >
        <p class="dialog-tip">
          请输入您对此章节的特定要求，AI将根据您的要求生成内容,如果不输入，将使用默认要求
        </p>
        <el-input
          v-model="userOpinion"
          type="textarea"
          :rows="5"
          placeholder="此处可以输入对AI生成章节内容的要求,如：希望在分析中加入更多图表数据的解读，生成字数在200字左右，使用简洁易懂的语言等..."
        />
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="userOpinionDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="confirmGenerateWithOpinion">
              <el-icon><Connection /></el-icon> 开始生成
            </el-button>
          </span>
        </template>
      </el-dialog>

      <!-- 添加批量生成用户意见输入对话框 -->
      <el-dialog
        v-model="batchUserOpinionDialogVisible"
        title="输入各章节报告分析内容的生成要求"
        width="50%"
        :close-on-click-modal="false"
      >
        <p class="dialog-tip">
          请输入您对所有选中章节的整体要求，AI将根据您的要求生成内容,直接点击生成则按默认要求生成
        </p>
        <el-input
          v-model="batchUserOpinion"
          type="textarea"
          :rows="5"
          placeholder="例如：希望所有章节使用专业风格，生成字数在200字左右,保持一致的语言风格，关注数据变化趋势等..."
        />
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="batchUserOpinionDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="confirmBatchGenerate">
              <el-icon><Connection /></el-icon> 开始生成
            </el-button>
          </span>
        </template>
      </el-dialog>

      <!-- 添加报表信息编辑对话框 -->
      <el-dialog
        v-model="reportInfoDialogVisible"
        title="编辑报表信息"
        width="50%"
        :close-on-click-modal="false"
      >
        <div class="report-info-form">
          <el-form label-position="top">
            <el-form-item label="报表标题">
              <el-input v-model="editingReportTitle" placeholder="请输入报表标题" />
            </el-form-item>
            <el-form-item label="报表描述">
              <el-input
                v-model="editingReportDescription"
                type="textarea"
                :rows="5"
                placeholder="请输入报表描述"
              />
            </el-form-item>
          </el-form>
        </div>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="reportInfoDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="saveReportInfo" :loading="updatingReportInfo">
              保存
            </el-button>
          </span>
        </template>
      </el-dialog>

      <!-- 添加修改数据范围对话框 -->
      <el-dialog
        v-model="dataRangeDialogVisible"
        title="修改数据范围"
        width="60%"
        :close-on-click-modal="false"
      >
        <div class="data-filter-container">
          <div class="filter-description glass-card">
            <el-alert type="info" :closable="false" show-icon>
              <template #title>
                <span>设置筛选条件可以帮助您聚焦于特定的数据子集，提高分析的针对性</span>
              </template>
              <p>所有修改将应用于整个报告的数据范围，可能会影响已生成的章节内容</p>
            </el-alert>
          </div>

          <!-- 数据范围筛选表单 -->
          <div class="filter-form-container glass-card" style="padding: 15px">
            <h4 class="filter-form-title">
              <el-icon><Filter /></el-icon>
              设置数据筛选条件
            </h4>

            <div class="filter-conditions">
              <div
                v-for="(condition, index) in filterConditions"
                :key="index"
                class="filter-condition-item"
              >
                <div class="condition-row">
                  <el-select
                    v-model="condition.field"
                    placeholder="选择字段"
                    filterable
                    class="condition-field"
                  >
                    <el-option
                      v-for="field in dataFields"
                      :key="field.name"
                      :label="field.display_name"
                      :value="field.name"
                    ></el-option>
                  </el-select>

                  <el-select
                    v-model="condition.operator"
                    placeholder="条件"
                    class="condition-operator"
                  >
                    <el-option
                      v-for="op in getOperatorsByFieldType(condition.field)"
                      :key="op.value"
                      :label="op.label"
                      :value="op.value"
                    ></el-option>
                  </el-select>

                  <div class="condition-value">
                    <!-- 日期选择器 -->
                    <el-date-picker
                      v-if="getFieldType(condition.field) === 'date'"
                      v-model="condition.value"
                      type="date"
                      placeholder="选择日期"
                      format="YYYY/MM/DD"
                      value-format="YYYY-MM-DD"
                    ></el-date-picker>

                    <!-- 数字输入框 -->
                    <el-input-number
                      v-else-if="getFieldType(condition.field) === 'number'"
                      v-model="condition.value"
                      :controls="false"
                      placeholder="输入数值"
                    ></el-input-number>

                    <!-- 文本输入框 -->
                    <el-input v-else v-model="condition.value" placeholder="输入值"></el-input>
                  </div>

                  <el-button
                    type="danger"
                    circle
                    size="small"
                    @click="removeFilterCondition(index)"
                    class="condition-remove-btn"
                  >
                    <el-icon><Delete /></el-icon>
                  </el-button>
                </div>
              </div>

              <div class="add-condition">
                <el-button type="primary" @click="addFilterCondition" class="add-condition-btn">
                  <el-icon><Plus /></el-icon>
                  添加筛选条件
                </el-button>
              </div>
            </div>

            <div class="filter-preview" v-if="filterConditions.length > 0">
              <div class="preview-title">当前筛选条件预览：</div>
              <div class="preview-content glass-card">
                <div class="preview-conditions-row">
                  <template v-for="(condition, index) in filterConditions" :key="index">
                    <span class="preview-condition-item">{{ getConditionText(condition) }}</span>
                    <span v-if="index < filterConditions.length - 1" class="condition-separator"
                      >且</span
                    >
                  </template>
                </div>
              </div>
            </div>
          </div>
        </div>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="dataRangeDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="saveDataRange" :loading="updatingDataRange">
              保存筛选条件
            </el-button>
          </span>
        </template>
      </el-dialog>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, nextTick, onMounted, watch } from 'vue'
import { useRoute } from 'vue-router'
import {
  Delete,
  Download,
  EditPen,
  Connection,
  View,
  Document,
  List,
  Check,
  Close,
  Refresh,
  Filter,
  Plus,
} from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { marked } from 'marked'
import {
  generateDimensionContent,
  getAnalysisDimension,
  getReportDetails,
  deleteDimension,
  generateAnalysisOutline,
  updateAnalysisResult,
  updateReportInfo,
  getDatasetInfo,
} from '../api/analysis'
import DataDisplayComponent from '../components/DataDisplayComponent.vue'

// 定义路由
const route = useRoute()

// 定义props接收从父组件传递的report-id
const props = defineProps({
  isDarkMode: {
    type: Boolean,
    default: false,
  },
  reportId: {
    type: [String, Number],
    default: '',
  },
})

// 定义状态变量
const reportTitle = ref('') // 报告标题
const reportRequirements = ref('') // 报告需求
const currentReportId = ref('') // 报告ID
const reportOutline = ref([]) // 存储报告大纲
const fullReport = ref('') // 完整报告内容
const selectedSection = ref(null) // 当前选中的章节
const generatingOutline = ref(false) // 是否正在生成大纲
const generatingReport = ref(false) // 是否正在生成报告
const generatingSectionContent = ref(false) // 是否正在生成章节内容
const generatingAllSections = ref(false) // 是否正在生成所有章节内容
const isEditingContent = ref(false) // 是否处于编辑模式
const fullReportDialogVisible = ref(false) // 完整报告预览对话框是否可见
const outlineTree = ref(null) // 大纲树引用
const nodeEditInput = ref(null) // 节点编辑输入框引用
const checkedNodes = ref({}) // 存储已勾选节点的Map
const pageLoading = ref(false) // 页面加载状态
const progressInfo = ref({ total: 0, completed: 0, failed: 0 }) // 进度信息
const userOpinionDialogVisible = ref(false)
const userOpinion = ref('')
const currentGeneratingSection = ref(null)
const batchUserOpinionDialogVisible = ref(false)
const batchUserOpinion = ref('')
const generatingOutlineStatus = ref(false) // 是否正在生成大纲
const activeTab = ref('reportedit') // 默认选中向导模式
// 添加保存内容状态变量
const savingContent = ref(false)
// 添加报表信息编辑对话框相关变量
const reportInfoDialogVisible = ref(false)
const editingReportTitle = ref('')
const editingReportDescription = ref('')
const updatingReportInfo = ref(false)
const clearingAllSections = ref(false)
// 数据范围相关变量
const dataRangeDialogVisible = ref(false)
const dataFields = ref([]) // 数据集字段列表
const filterConditions = ref([]) // 筛选条件列表
const fieldTypeMap = ref(new Map()) // 字段名到类型的映射
const updatingDataRange = ref(false)
const datasetId = ref('') // 存储数据集ID

// 操作符列表定义
const stringOperators = [
  { label: '等于', value: 'eq' },
  { label: '包含', value: 'contains' },
  { label: '开始于', value: 'startsWith' },
  { label: '结束于', value: 'endsWith' },
]

const numberOperators = [
  { label: '等于', value: 'eq' },
  { label: '大于', value: 'gt' },
  { label: '小于', value: 'lt' },
  { label: '大于等于', value: 'gte' },
  { label: '小于等于', value: 'lte' },
  { label: '不等于', value: 'ne' },
]

const dateOperators = [
  { label: '等于', value: 'eq' },
  { label: '小于', value: 'lt' },
  { label: '大于', value: 'gt' },
]

// 计算属性 - 树形结构的大纲
const treeOutline = computed(() => {
  // 处理为空的情况
  if (!reportOutline.value || reportOutline.value.length === 0) {
    return []
  }

  // 使用Map按analysis_goal分组
  const goalMap = new Map()

  // 遍历dimensions数组，按analysis_goal分组
  reportOutline.value.forEach((dimension) => {
    const goalName = dimension.analysis_goal

    // 如果Map中还没有这个analysis_goal，创建父节点
    if (!goalMap.has(goalName)) {
      goalMap.set(goalName, {
        id: dimension.id || generateId(), // 使用现有ID或生成新ID
        title: goalName,
        content: `${goalName}的综合分析...`,
        isEditing: false,
        status: 'pending',
        children: [], // 初始化子节点数组
      })
    }

    // 确保status字段存在且有效
    const nodeStatus = dimension.status || (dimension.analysis_result ? 'completed' : 'pending')

    // 将当前维度添加到对应的父节点的children数组
    goalMap.get(goalName).children.push({
      ...dimension, // 保留原始数据的所有属性
      id: dimension.id || generateId(), // 使用现有ID或生成新ID
      title: dimension.dimension_name, // 原始标题，稍后会添加序号
      content: dimension.dimension_description || '',
      parentId: `goal-${goalName}`, // 链接到父节点
      status: nodeStatus, // 确保使用正确的状态
      isEditing: false,
    })
  })

  // 处理父节点和子节点的序号
  let parentIndex = 1
  const result = Array.from(goalMap.values()).map((parent) => {
    // 添加父节点序号
    parent.title = `${parentIndex}. ${parent.title}`

    // 添加子节点序号
    if (parent.children && parent.children.length > 0) {
      parent.children.forEach((child, childIndex) => {
        child.title = `${parentIndex}.${childIndex + 1} ${child.title}`
      })
    }

    parentIndex++
    return parent
  })

  return result
})

// 计算属性 - 完整报告的渲染内容
const renderedReport = computed(() => {
  return marked.parse(fullReport.value || '')
})

// 处理JSON数据的计算属性
const parsedJsonData = computed(() => {
  if (!selectedSection.value || !selectedSection.value.json_data) {
    return null
  }

  try {
    // 如果已经是对象，直接使用
    if (typeof selectedSection.value.json_data === 'object') {
      // 如果是数组直接返回
      if (Array.isArray(selectedSection.value.json_data)) {
        return selectedSection.value.json_data
      }
      // 如果是对象，转换为数组格式以便表格显示
      return [selectedSection.value.json_data]
    }

    // 如果是字符串，尝试解析
    const jsonData = JSON.parse(selectedSection.value.json_data)
    if (Array.isArray(jsonData)) {
      return jsonData
    }
    return [jsonData] // 单个对象包装为数组
  } catch (error) {
    console.error('JSON解析错误:', error)
    return null
  }
})

// 动态生成表格列
const jsonDataColumns = computed(() => {
  if (!parsedJsonData.value || parsedJsonData.value.length === 0) {
    return []
  }

  // 从第一个对象获取所有键作为列
  const firstItem = parsedJsonData.value[0]
  return Object.keys(firstItem).map((key) => ({
    prop: key,
    label: key.charAt(0).toUpperCase() + key.slice(1).replace(/_/g, ' '),
    width: '',
  }))
})

// 生命周期钩子 - 组件挂载时
onMounted(async () => {
  // 优先从路由参数中获取报告ID，如果没有则使用props中的值
  if (route.params.reportId) {
    currentReportId.value = route.params.reportId
  } else if (props.reportId) {
    currentReportId.value = props.reportId
  }

  if (currentReportId.value) {
    await loadReportDetails()
  } else {
    ElMessage.warning('未找到报告ID，请返回选择报告')
  }
})

// 监听reportId的变化，重新加载报告详情
watch(
  () => props.reportId,
  async (newReportId) => {
    // 只有当新值存在且与当前不同时才重新加载
    if (newReportId && newReportId !== currentReportId.value) {
      currentReportId.value = newReportId
      // 重置页面状态
      selectedSection.value = null
      reportOutline.value = []
      // 加载新报告详情
      await loadReportDetails()
    }
  },
)

// 监听路由参数的变化
watch(
  () => route.params.reportId,
  async (newReportId) => {
    if (newReportId && newReportId !== currentReportId.value) {
      currentReportId.value = newReportId
      // 重置页面状态
      selectedSection.value = null
      reportOutline.value = []
      // 加载新报告详情
      await loadReportDetails()
    }
  },
)

// 加载报告详情
const loadReportDetails = async () => {
  if (!currentReportId.value) return

  try {
    const response = await getReportDetails(currentReportId.value)

    if (response.status === 'success') {
      // 设置基本信息
      reportTitle.value = response.report?.report_title || '未命名报告'
      reportRequirements.value = response.report?.report_description || ''

      // 加载筛选条件
      if (response.report?.data_filters && JSON.parse(response.report.data_filters).length > 0) {
        filterConditions.value = JSON.parse(response.report.data_filters).map((filter) => ({
          field: filter.field,
          operator: filter.operator,
          value: filter.value,
        }))
      } else {
        filterConditions.value = []
      }

      // 保存数据集ID，以便后续使用
      if (response.report?.dataset_id) {
        datasetId.value = response.report.dataset_id

        // 初始化时加载数据集字段信息
        await fetchDatasetFields(response.report.dataset_id)
      }

      // 设置大纲结构
      if (response.dimensions) {
        reportOutline.value = response.dimensions

        // 初始化节点选中状态
        reportOutline.value.forEach((node) => {
          checkedNodes.value[node.id] = false
        })

        // 自动选择第一个章节
        if (reportOutline.value.length > 0) {
          const firstMainNode = reportOutline.value.find((section) => !section.isChildNode)

          if (firstMainNode) {
            selectedSection.value = { ...firstMainNode }
            const childNodes = reportOutline.value.filter(
              (section) => section.isChildNode && section.goalId === firstMainNode.id,
            )

            if (childNodes.length > 0) {
              selectedSection.value.children = childNodes
            }
          } else {
            selectedSection.value = { ...reportOutline.value[0] }
          }

          // 检查是否所有章节都没有内容，如果是，询问用户是否自动生成全部
          nextTick(() => {
            checkAndPromptForGeneration()
          })
        }
      }
    } else {
      throw new Error(response.message || '加载报告详情失败')
    }
  } catch (error) {
    console.error('加载报告详情出错:', error)
    ElMessage.error(`加载报告详情失败: ${error.message || '请重试'}`)
  }
}

// 加载数据集字段信息
const fetchDatasetFields = async (datasetId) => {
  try {
    if (!datasetId) {
      throw new Error('未提供数据集ID')
    }

    const response = await getDatasetInfo(datasetId)

    if (response.status && response.fields) {
      dataFields.value = response.fields.map((field) => {
        // 推断字段类型
        let fieldType = 'string'
        if (
          field.data_type === 'number' ||
          field.data_type === 'integer' ||
          field.data_type === 'float' ||
          field.data_type === 'decimal'
        ) {
          fieldType = 'number'
        } else if (field.data_type === 'date' || field.data_type === 'datetime') {
          fieldType = 'date'
        }
        // 存储字段类型
        fieldTypeMap.value.set(field.name, fieldType)

        return {
          ...field,
          fieldType, // 添加字段类型信息
        }
      })
    } else {
      dataFields.value = []
    }
  } catch (error) {
    console.error('获取数据集字段失败:', error)
    ElMessage.error('获取数据集字段失败')
    dataFields.value = []
  }
}

// 检查所有章节是否为空并提示生成
const checkAndPromptForGeneration = () => {
  // 获取所有需要检查内容的章节（非父节点）
  const allLeafSections = reportOutline.value.filter(
    (section) => !section.isParent && (!section.children || section.children.length === 0),
  )

  // 检查是否所有章节都没有内容
  const allEmpty = allLeafSections.every(
    (section) => !section.analysis_result || section.analysis_result.trim() === '',
  )

  // 如果全部为空且有章节需要生成
  if (allEmpty && allLeafSections.length > 0) {
    ElMessageBox.confirm('检测到当前报告所有章节都没有内容，是否自动生成所有章节内容？', '提示', {
      confirmButtonText: '立即生成',
      cancelButtonText: '稍后手动生成',
      type: 'info',
      closeOnClickModal: false,
    })
      .then(() => {
        // 选中所有章节
        selectAllNodes()
        // 显示批量生成对话框
        showBatchUserOpinionDialog()
      })
      .catch(() => {
        // 用户取消，不执行任何操作
      })
  }
}

// 选中所有节点
const selectAllNodes = () => {
  // 获取所有子节点
  const allLeafNodes = treeOutline.value.flatMap((parent) =>
    parent.children ? parent.children.filter((child) => !child.children) : [],
  )

  // 更新选中状态
  allLeafNodes.forEach((node) => {
    checkedNodes.value[node.id] = true
  })
}

// 生成所有章节的内容（修改为只处理选中节点）
const generateAllSectionsContent = async (userOpinionText = '') => {
  // 获取所有选中的节点ID
  const selectedNodeIds = Object.entries(checkedNodes.value)
    .filter(([, isChecked]) => isChecked)
    .map(([id]) => id)

  if (selectedNodeIds.length === 0) {
    ElMessage.warning('请先勾选要生成内容的章节')
    return
  }

  generatingAllSections.value = true
  pageLoading.value = true // 设置页面loading状态，阻止用户操作

  // 重置进度信息
  progressInfo.value = {
    total: 0,
    completed: 0,
    failed: 0,
  }

  try {
    // 收集所有被选中的子节点
    const allSections = reportOutline.value.filter(
      // 只考虑被选中、有id的节点且不是父节点
      (item) => selectedNodeIds.includes(item.id) && !item.children && !item.isParent,
    )

    // 更新总数
    progressInfo.value.total = allSections.length

    if (allSections.length === 0) {
      ElMessage.warning('没有找到有效的被选中节点')
      return
    }

    // 创建一个并发控制队列，限制同时最多5个请求
    const concurrencyLimit = 5
    const queue = []
    const results = []

    for (const section of allSections) {
      // 每个章节创建一个处理函数
      const process = async () => {
        try {
          // 更新状态为生成中，同时确保在原始数据和树节点上都更新状态
          section.status = 'in_progress'

          // 在原始数据中查找并更新状态
          const originalNode = reportOutline.value.find((item) => item.id === section.id)
          if (originalNode) {
            originalNode.status = 'in_progress'
          }

          // 直接更新树的节点状态，确保UI立即反映
          treeOutline.value.forEach((parent) => {
            if (parent.children) {
              const child = parent.children.find((c) => c.id === section.id)
              if (child) {
                child.status = 'in_progress'
              }
            }
          })

          // 在这里立即应用一次强制更新，让状态改变立即可见
          nextTick(() => {
            if (outlineTree.value) {
              outlineTree.value.$forceUpdate()
            }
          })

          // 调用API生成内容，传递用户意见参数
          const response = await generateDimensionContent(section.id, userOpinionText)

          if (response && response.status) {
            // 更新状态为已完成
            section.status = 'completed'
            section.analysis_result = response.dimension.analysis_result

            // 同步更新原始数据和树节点状态
            if (originalNode) {
              originalNode.status = 'completed'
              originalNode.analysis_result = response.dimension.analysis_result
            }

            // 更新树节点
            let treeNodeUpdated = false
            treeOutline.value.forEach((parent) => {
              if (parent.children) {
                const child = parent.children.find((c) => c.id === section.id)
                if (child) {
                  child.status = 'completed'
                  child.analysis_result = response.dimension.analysis_result
                  treeNodeUpdated = true
                }
              }
            })

            // 如果当前章节是选中的章节，也更新选中章节的状态
            if (selectedSection.value && selectedSection.value.id === section.id) {
              selectedSection.value.status = 'completed'
              selectedSection.value.analysis_result = response.dimension.analysis_result
            }

            // 更新进度
            progressInfo.value.completed++

            return { id: section.id, success: true, updated: treeNodeUpdated }
          } else {
            throw new Error(response?.message || '生成内容失败')
          }
        } catch (error) {
          // 更新状态为失败
          section.status = 'failed'

          // 同步更新原始数据
          const originalNode = reportOutline.value.find((item) => item.id === section.id)
          if (originalNode) {
            originalNode.status = 'failed'
          }

          // 更新树节点
          treeOutline.value.forEach((parent) => {
            if (parent.children) {
              const child = parent.children.find((c) => c.id === section.id)
              if (child) {
                child.status = 'failed'
              }
            }
          })

          // 更新进度
          progressInfo.value.failed++

          return { id: section.id, success: false, error: error.message }
        }
      }

      // 将处理函数添加到队列
      queue.push(process)
    }

    // 执行队列中的任务，控制并发数量
    while (queue.length > 0) {
      // 取出要执行的任务数量（不超过并发限制和剩余任务数）
      const currentBatch = queue.splice(0, Math.min(concurrencyLimit, queue.length))

      // 并发执行这一批任务
      const batchResults = await Promise.all(currentBatch.map((task) => task()))

      // 收集结果
      results.push(...batchResults)

      // 每批次完成后，强制更新树视图
      nextTick(() => {
        if (outlineTree.value) {
          outlineTree.value.$forceUpdate()
        }
      })

      // 添加一小段延迟，避免UI阻塞
      if (queue.length > 0) {
        await new Promise((resolve) => setTimeout(resolve, 100))
      }
    }
    // 再次强制刷新树视图
    nextTick(() => {
      if (outlineTree.value) {
        outlineTree.value.$forceUpdate()
      }

      // 再刷新一次，确保最终状态一致（有时可能需要两次渲染）
      setTimeout(() => {
        if (outlineTree.value) {
          outlineTree.value.$forceUpdate()
        }
      }, 300)
    })

    // 统计结果
    const successCount = results.filter((result) => result && result.success).length
    const failedCount = progressInfo.value.failed

    // 显示最终结果
    if (failedCount === 0) {
      ElMessage.success(`成功生成 ${successCount} 个章节内容`)
    } else if (successCount === 0) {
      ElMessage.error(`所有 ${failedCount} 个章节内容生成失败`)
    } else {
      ElMessage({
        type: 'warning',
        message: `成功生成 ${successCount} 个章节内容，${failedCount} 个章节失败`,
      })
    }
  } catch (error) {
    console.error('生成所有章节内容过程中发生错误:', error)
    ElMessage.error('生成过程中发生错误，请重试')
  } finally {
    generatingAllSections.value = false
    pageLoading.value = false // 恢复页面可操作状态
  }
}

// 处理导出选项
const handleExport = (command) => {
  if (command === 'markdown') {
    exportReportAsMarkdown()
  } else if (command === 'pdf') {
    exportReportAsPDF()
  }
}

// 导出报告为PDF
const exportReportAsPDF = () => {
  if (!fullReport.value) {
    ElMessage.warning('暂无报告内容可导出')
    return
  }

  // 这里是PDF导出的实现
  // 实际项目中可能需要调用专门的PDF生成库或服务
  ElMessage.success('PDF导出功能正在开发中')
}

// 导出报告为Markdown
const exportReportAsMarkdown = () => {
  if (!fullReport.value) {
    ElMessage.warning('暂无报告内容可导出')
    return
  }

  try {
    // 创建Blob对象
    const blob = new Blob([fullReport.value], { type: 'text/markdown;charset=utf-8;' })

    // 创建下载链接
    const link = document.createElement('a')
    link.href = URL.createObjectURL(blob)
    link.download = `${reportTitle.value || '数据分析报告'}.md`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)

    ElMessage.success('报告已导出为Markdown文件')
  } catch (error) {
    console.error('导出Markdown失败:', error)
    ElMessage.error('导出失败，请重试')
  }
}

// 编辑内容状态切换
const toggleEditMode = () => {
  isEditingContent.value = !isEditingContent.value
}

// 处理树节点点击
const handleNodeClick = async (data) => {
  if (!data.children) {
    const response = await getAnalysisDimension(data.id)
    if (response.status === 'success' && response.data) {
      const dimensionData = response.data
      selectedSection.value = { ...dimensionData }
    }
  }
  // 默认进入预览模式
  isEditingContent.value = false
}

// 开始编辑节点标题
const startEditNode = (data) => {
  data.isEditing = true
  nextTick(() => {
    if (nodeEditInput.value) {
      nodeEditInput.value.focus()
    }
  })
}

// 完成编辑节点标题
const finishEditNode = (data) => {
  data.isEditing = false

  // 更新原始大纲中的标题
  const originalItem = reportOutline.value.find((item) => item.id === data.id)
  if (originalItem) {
    originalItem.title = data.title
  }

  // 如果当前选中的是这个节点，也更新选中节点
  if (selectedSection.value && selectedSection.value.id === data.id) {
    selectedSection.value.title = data.title
  }
}

// 更新章节内容
const updateSectionContent = () => {
  // 更新原始大纲中的内容
  if (selectedSection.value) {
    const originalItem = reportOutline.value.find((item) => item.id === selectedSection.value.id)
    if (originalItem) {
      originalItem.content = selectedSection.value.content
    }
  }
}

// 添加保存章节内容的方法
const saveAnalysisContent = async () => {
  if (!selectedSection.value || !selectedSection.value.id) {
    ElMessage.warning('当前没有选中章节，无法保存')
    return
  }

  savingContent.value = true

  try {
    const loadingInstance = ElMessage({
      type: 'info',
      message: '正在保存章节内容...',
      duration: 0,
    })

    // 调用API保存内容
    const response = await updateAnalysisResult(
      selectedSection.value.id,
      selectedSection.value.analysis_result,
    )

    if (response && response.status) {
      // 更新原始大纲中的内容
      const originalItem = reportOutline.value.find((item) => item.id === selectedSection.value.id)
      if (originalItem) {
        originalItem.analysis_result = selectedSection.value.analysis_result
      }

      // 更新树节点中的内容
      const treeNode = treeOutline.value
        .flatMap((parent) => [parent, ...(parent.children || [])])
        .find((node) => node.id === selectedSection.value.id)

      if (treeNode) {
        treeNode.analysis_result = selectedSection.value.analysis_result
      }

      // 切换回预览模式
      isEditingContent.value = false
      ElMessage.success('章节内容已保存')
    } else {
      throw new Error(response?.message || '保存内容失败')
    }

    loadingInstance.close()
  } catch (error) {
    console.error('保存章节内容失败:', error)
    ElMessage.error(`保存失败: ${error.message || '请重试'}`)
  } finally {
    savingContent.value = false
  }
}

// 定义允许拖拽的规则
const allowDrag = (node) => {
  // 根据节点类型设置拖拽规则
  // 检查节点是否有效
  if (!node || !node.data) {
    return false
  }
  // 允许所有节点拖动
  return true
}

// 定义允许放置的规则
const allowDrop = (draggingNode, dropNode, type) => {
  // 如果是拖到节点上（成为其子节点）
  if (type === 'inner') {
    // 只允许父节点包含子节点，子节点不能再包含其他节点
    return dropNode.data.children && !draggingNode.data.children
  }

  // 如果是拖到节点前或后
  if (type === 'before' || type === 'after') {
    // 只允许相同层级的节点之间拖动
    return draggingNode.level === dropNode.level
  }

  return false
}

// 处理拖拽结束
const handleDragEnd = (draggingNode) => {
  try {
    console.log('拖拽结束事件触发', draggingNode ? draggingNode.data : '无拖拽节点')

    if (!outlineTree.value) {
      console.warn('树组件引用不存在，无法完成拖拽后的更新')
      return
    }

    // 创建一个函数来收集树的当前结构
    const collectTreeStructure = () => {
      try {
        const treeData = outlineTree.value.store.nodesMap
        const rootNodes = Object.values(treeData).filter(
          (node) => !node.parent || node.parent.key === null,
        )

        // 按当前树的顺序排序根节点
        rootNodes.sort((a, b) => {
          return a.level === b.level ? a.index - b.index : a.level - b.level
        })

        console.log('当前树结构根节点数量:', rootNodes.length)

        // 重新构建完整的数据结构
        const newStructure = []

        rootNodes.forEach((rootNode, rootIndex) => {
          // 在原始数据中查找对应的节点
          const originalNode = reportOutline.value.find((item) => item.id === rootNode.data.id)

          if (originalNode) {
            // 创建新的根节点数据
            const newRootNode = {
              ...originalNode,
              title: `${rootIndex + 1}. ${originalNode.analysis_goal || originalNode.title.split(' ').slice(1).join(' ')}`,
              children: [],
            }

            // 添加所有子节点
            if (rootNode.childNodes && rootNode.childNodes.length > 0) {
              rootNode.childNodes.forEach((childNode, childIndex) => {
                const originalChild = reportOutline.value.find(
                  (item) => item.id === childNode.data.id,
                )

                if (originalChild) {
                  // 计算新的子节点标题，确保序号正确
                  const childTitle = `${rootIndex + 1}.${childIndex + 1} ${originalChild.dimension_name || originalChild.title.split(' ').slice(1).join(' ')}`

                  // 添加到新父节点的子节点列表
                  newRootNode.children.push({
                    ...originalChild,
                    title: childTitle,
                    parentId: newRootNode.id,
                  })
                }
              })
            }

            newStructure.push(newRootNode)
          }
        })

        return newStructure
      } catch (error) {
        console.error('收集树结构时发生错误:', error)
        return []
      }
    }

    // 获取新的结构并更新数据
    const newOutline = collectTreeStructure()

    if (newOutline.length > 0) {
      console.log('已收集到更新后的大纲结构，节点数量:', newOutline.length)

      // 更新reportOutline
      reportOutline.value = [...newOutline]

      // 强制刷新树视图
      nextTick(() => {
        // 更新树的视图
        if (outlineTree.value) {
          outlineTree.value.$forceUpdate()
        }

        // 如果拖动的节点是当前选中的节点，也需要更新selectedSection
        if (
          selectedSection.value &&
          draggingNode &&
          selectedSection.value.id === draggingNode.data.id
        ) {
          // 在新结构中找到对应的节点
          const flattenedNodes = newOutline.flatMap((parent) => [
            parent,
            ...(parent.children || []),
          ])
          const updatedNode = flattenedNodes.find((node) => node.id === selectedSection.value.id)

          if (updatedNode) {
            selectedSection.value = { ...updatedNode }
          }
        }

        // 拖拽完成后检查结构
        console.log('拖拽后更新的大纲结构:', JSON.stringify(newOutline))
      })
    } else {
      console.warn('未能收集到有效的大纲结构')
    }
  } catch (error) {
    console.error('拖拽处理过程中发生错误:', error)
    ElMessage.error('更新章节顺序失败，请刷新页面后重试')
  }
}

// 用于生成唯一ID的简单函数
const generateId = () => {
  return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
}

// 处理节点勾选变化
// 此代码暂时被注释掉，因为我们现在不需要这个功能
// 如果将来需要恢复，可以去掉注释
/*
const handleNodeCheckChange = (node) => {
  const isChecked = checkedNodes.value[node.id]

  // 如果是父节点，更新所有子节点
  if (node.children && node.children.length > 0) {
    node.children.forEach((child) => {
      checkedNodes.value[child.id] = isChecked
    })
  }

  // 如果是子节点，检查是否需要更新父节点状态
  else if (node.parentId) {
    // 找到父节点
    const parentNode = treeOutline.value.find(
      (parent) => parent.id === node.parentId || parent.id === node.parentId.replace('goal-', ''),
    )
    if (parentNode) {
      // 检查所有子节点是否都选中或都未选中
      const allChildren = parentNode.children || []
      const allChecked = allChildren.every((child) => checkedNodes.value[child.id])
      const allUnchecked = allChildren.every((child) => !checkedNodes.value[child.id])

      // 更新父节点状态
      if (allChecked) {
        checkedNodes.value[parentNode.id] = true
      } else if (allUnchecked) {
        checkedNodes.value[parentNode.id] = false
      }
    }
  }
}
*/

// 添加Markdown渲染函数
const renderedMarkdown = (content) => {
  if (!content) return ''
  try {
    // 使用marked库解析Markdown内容为HTML
    return marked.parse(content)
  } catch (error) {
    console.error('Markdown解析错误:', error)
    // 发生错误时返回原始内容，至少保证内容显示
    return `<div class="markdown-error">
      <p style="color: #f56c6c;">Markdown渲染错误，显示原始内容：</p>
      <pre>${content}</pre>
    </div>`
  }
}

// 添加显示用户输入对话框的方法
const showUserOpinionDialog = (section) => {
  currentGeneratingSection.value = section
  userOpinion.value = '' // 清空之前的输入
  userOpinionDialogVisible.value = true
}

// 添加确认生成的方法
const confirmGenerateWithOpinion = () => {
  if (!currentGeneratingSection.value) return

  userOpinionDialogVisible.value = false
  generateSectionContent(currentGeneratingSection.value, userOpinion.value)
}

// 修改生成章节内容的方法，添加user_opinion参数
const generateSectionContent = async (section, userOpinionText = '') => {
  if (!section || !section.id) {
    ElMessage.warning('缺少维度ID，无法生成内容')
    return
  }

  generatingSectionContent.value = true

  try {
    // 设置状态为生成中
    section.status = 'in_progress'

    // 更新原始大纲中对应节点的状态
    const treeNode = treeOutline.value
      .flatMap((parent) => [parent, ...(parent.children || [])])
      .find((node) => node.id === section.id)

    if (treeNode) {
      treeNode.status = 'in_progress'
    }

    // 更新原始数据中的状态
    const originalNode = reportOutline.value.find((item) => item.id === section.id)
    if (originalNode) {
      originalNode.status = 'in_progress'
    }

    // 调用分析维度生成API，添加user_opinion参数
    const response = await generateDimensionContent(section.id, userOpinionText)
    if (response.status) {
      // 更新分析结果
      section.analysis_result = response.dimension.analysis_result
      section.status = 'completed'

      // 刷新页面显示的内容
      selectedSection.value = { ...section }

      // 更新原始数据中的状态和内容
      if (originalNode) {
        originalNode.analysis_result = section.analysis_result
        originalNode.status = 'completed'
      }

      // 更新树节点状态
      if (treeNode) {
        treeNode.status = 'completed'
        treeNode.analysis_result = section.analysis_result
      }

      // 强制刷新树视图
      nextTick(() => {
        if (outlineTree.value) {
          outlineTree.value.$forceUpdate()
        }
      })

      ElMessage.success('分析内容生成成功')
    } else {
      throw new Error(response?.message || '生成内容失败')
    }
  } catch (error) {
    console.error('生成内容失败:', error)
    section.status = 'failed'

    // 更新原始数据状态
    const originalNode = reportOutline.value.find((item) => item.id === section.id)
    if (originalNode) {
      originalNode.status = 'failed'
    }

    // 更新树节点状态
    const treeNode = treeOutline.value
      .flatMap((parent) => [parent, ...(parent.children || [])])
      .find((node) => node.id === section.id)

    if (treeNode) {
      treeNode.status = 'failed'
    }

    ElMessage.error(`生成内容失败: ${error.message || '请重试'}`)
  } finally {
    generatingSectionContent.value = false
  }
}

// 添加显示批量生成用户意见对话框的方法
const showBatchUserOpinionDialog = () => {
  // 获取所有选中的节点ID
  const selectedNodeIds = Object.entries(checkedNodes.value)
    .filter(([, isChecked]) => isChecked)
    .map(([id]) => id)

  if (selectedNodeIds.length === 0) {
    ElMessage.warning('请先勾选要生成内容的章节')
    return
  }

  batchUserOpinion.value = '' // 清空之前的输入
  batchUserOpinionDialogVisible.value = true
}

// 添加确认批量生成的方法
const confirmBatchGenerate = () => {
  batchUserOpinionDialogVisible.value = false

  // 查找所有没有内容的章节
  const emptyNodes = []

  // 遍历reportOutline获取所有无内容的章节
  reportOutline.value.forEach((node) => {
    if (
      !node.isParent &&
      !node.children &&
      (!node.analysis_result || node.analysis_result.trim() === '')
    ) {
      emptyNodes.push(node)
    }
  })

  if (emptyNodes.length === 0) {
    ElMessage.info('所有章节都已有内容，无需生成')
    return
  }

  // 为所有空节点设置选中状态
  emptyNodes.forEach((node) => {
    checkedNodes.value[node.id] = true
  })

  // 调用已有的生成内容方法
  generateAllSectionsContent(batchUserOpinion.value)
}

// 打开报告预览页面
const openReportDisplayPage = () => {
  if (!currentReportId.value) {
    ElMessage.warning('当前没有可预览的报告')
    return
  }

  // 打开新窗口并传递报告ID参数
  window.open(`/report_display.html?report_id=${currentReportId.value}`, '_blank')
}

// 生成分析大纲
const generateOutline = async () => {
  if (!currentReportId.value) {
    ElMessage.warning('请先加载报告')
    return
  }

  try {
    generatingOutlineStatus.value = true
    const response = await generateAnalysisOutline(currentReportId.value)

    if (response.status) {
      ElMessage.success('分析大纲生成成功')
      // 重新加载报告详情以获取最新大纲
      await loadReportDetails()
    } else {
      throw new Error(response.message || '生成分析大纲失败')
    }
  } catch (error) {
    console.error('生成分析大纲出错:', error)
    ElMessage.error(`生成分析大纲失败: ${error.message || '请重试'}`)
  } finally {
    generatingOutlineStatus.value = false
  }
}

// 添加一键生成所有空章节的方法
const generateAllEmptySections = async () => {
  // 显示生成要求对话框
  batchUserOpinion.value = '' // 清空之前的输入
  batchUserOpinionDialogVisible.value = true
}

// 删除单个节点
const deleteNode = async (node) => {
  if (!node || !node.id) {
    ElMessage.warning('无效的节点')
    return
  }

  // 父节点不能删除
  if (node.children && node.children.length > 0) {
    ElMessage.warning('父节点不能直接删除，请先删除其下的子节点')
    return
  }

  try {
    await ElMessageBox.confirm(
      `确定要删除章节 "${node.title}" 吗？删除后内容将无法恢复。`,
      '删除确认',
      {
        confirmButtonText: '确定删除',
        cancelButtonText: '取消',
        type: 'warning',
      },
    )

    // 显示加载状态
    const loadingInstance = ElMessage({
      type: 'info',
      message: `正在删除章节，请稍候...`,
      duration: 0,
    })

    // 调用接口删除
    const response = await deleteDimension(node.id)

    if (response && response.status === 'success') {
      // 从本地数据中删除
      const index = reportOutline.value.findIndex((item) => item.id === node.id)
      if (index !== -1) {
        reportOutline.value.splice(index, 1)

        // 如果删除的是当前选中的，则选择第一个章节
        if (selectedSection.value && selectedSection.value.id === node.id) {
          selectedSection.value =
            reportOutline.value.length > 0 ? { ...reportOutline.value[0] } : null
        }
      }

      ElMessage.success('章节已成功删除')
    } else {
      throw new Error(response?.message || '删除失败')
    }

    // 关闭加载提示
    loadingInstance.close()

    // 强制刷新树视图
    nextTick(() => {
      if (outlineTree.value) {
        outlineTree.value.$forceUpdate()
      }
    })
  } catch (error) {
    if (error === 'cancel') {
      // 用户取消删除，不做处理
      return
    }
    console.error('删除章节失败:', error)
    ElMessage.error(`删除失败: ${error.message || '请重试'}`)
  }
}

// 添加保存报表信息的方法
const saveReportInfo = async () => {
  if (!editingReportTitle.value || !editingReportDescription.value) {
    ElMessage.warning('报表标题和描述不能为空')
    return
  }

  updatingReportInfo.value = true

  try {
    const response = await updateReportInfo(
      currentReportId.value,
      editingReportTitle.value,
      editingReportDescription.value,
    )

    if (response && response.status) {
      reportTitle.value = editingReportTitle.value
      reportRequirements.value = editingReportDescription.value
      ElMessage.success('报表信息保存成功')
      reportInfoDialogVisible.value = false
    } else {
      throw new Error(response?.message || '保存报表信息失败')
    }
  } catch (error) {
    console.error('保存报表信息出错:', error)
    ElMessage.error(`保存失败: ${error.message || '请重试'}`)
  } finally {
    updatingReportInfo.value = false
  }
}

// 添加显示报表信息对话框的方法
const showReportInfoDialog = () => {
  editingReportTitle.value = reportTitle.value
  editingReportDescription.value = reportRequirements.value
  reportInfoDialogVisible.value = true
}

// 处理数据导出
const handleDataExport = (data) => {
  // 这里可以添加处理数据导出的逻辑
  console.log('导出数据:', data)
}

// 添加清除所有章节内容的方法
const clearAllSections = async () => {
  try {
    // 显示确认对话框
    await ElMessageBox.confirm('确定要清除所有章节的分析内容吗？此操作不可恢复。', '警告', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })

    clearingAllSections.value = true

    // 获取所有章节ID
    const sectionIds = treeOutline.value
      .flatMap((parent) => [parent, ...(parent.children || [])])
      .filter((node) => !node.children) // 只获取叶子节点
      .map((node) => node.id)
      .join(',')

    if (!sectionIds) {
      ElMessage.warning('没有找到可清除的章节')
      return
    }

    // 调用API清除内容
    const response = await updateAnalysisResult(sectionIds, '')

    if (response.status) {
      // 更新所有章节的状态
      treeOutline.value.forEach((parent) => {
        if (parent.children) {
          parent.children.forEach((child) => {
            child.analysis_result = ''
            child.status = 'pending'
          })
        }
      })

      // 更新 reportOutline 中的状态
      reportOutline.value.forEach((dimension) => {
        if (sectionIds.includes(dimension.id)) {
          dimension.analysis_result = ''
          dimension.status = 'pending'
        }
      })

      // 如果当前选中的章节在清除范围内，也更新其内容
      if (selectedSection.value && sectionIds.includes(selectedSection.value.id)) {
        selectedSection.value.analysis_result = ''
        selectedSection.value.status = 'pending'
      }

      // 强制刷新树视图
      nextTick(() => {
        if (outlineTree.value) {
          outlineTree.value.$forceUpdate()
        }
      })

      ElMessage.success('所有章节内容已清除')
    } else {
      throw new Error(response?.message || '清除内容失败')
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('清除章节内容失败:', error)
      ElMessage.error(`清除失败: ${error.message || '请重试'}`)
    }
  } finally {
    clearingAllSections.value = false
  }
}

// 获取字段类型
const getFieldType = (fieldName) => {
  if (!fieldName) return 'string'
  return fieldTypeMap.value.get(fieldName) || 'string'
}

// 根据字段类型获取可用的操作符
const getOperatorsByFieldType = (fieldName) => {
  const fieldType = getFieldType(fieldName)
  switch (fieldType) {
    case 'number':
      return numberOperators
    case 'date':
      return dateOperators
    default:
      return stringOperators
  }
}

// 添加筛选条件
const addFilterCondition = () => {
  filterConditions.value.push({
    field: '',
    operator: '',
    value: '',
  })
}

// 移除筛选条件
const removeFilterCondition = (index) => {
  filterConditions.value.splice(index, 1)
}

// 根据筛选条件获取显示文本
const getConditionText = (condition) => {
  if (!condition.field || !condition.operator) return ''

  // 查找字段的显示名称
  const field = dataFields.value.find((f) => f.name === condition.field)
  const fieldDisplayName = field ? field.display_name : condition.field

  // 查找操作符显示文本
  const operatorList = getOperatorsByFieldType(condition.field)
  const operatorText =
    operatorList.find((op) => op.value === condition.operator)?.label || condition.operator

  let valueText = condition.value
  const fieldType = getFieldType(condition.field)

  // 格式化日期显示
  if (fieldType === 'date' && condition.value) {
    try {
      valueText = new Date(condition.value).toLocaleDateString()
    } catch {
      // 如果日期格式有问题，使用原始值
    }
  }

  return `${fieldDisplayName} ${operatorText} ${valueText}`
}

// 显示修改数据范围对话框
const showDataRangeDialog = () => {
  // 直接打开对话框，数据已在loadReportDetails中加载
  dataRangeDialogVisible.value = true
}

// 保存数据范围
const saveDataRange = async () => {
  try {
    updatingDataRange.value = true

    // 验证筛选条件是否完整
    const invalidConditions = filterConditions.value.filter(
      (c) => !c.field || !c.operator || c.value === undefined || c.value === '',
    )

    if (invalidConditions.length > 0) {
      ElMessage.warning('存在未完成的筛选条件，请完善或删除')
      return
    }

    // 准备筛选条件数据
    const filters = filterConditions.value.map((c) => ({
      field: c.field,
      operator: c.operator,
      value: c.value,
      description: getConditionText(c),
    }))

    // 调用API更新报告筛选条件
    const response = await updateReportInfo(currentReportId.value, '', '', JSON.stringify(filters))

    if (response.status) {
      ElMessage.success('数据范围更新成功')
      dataRangeDialogVisible.value = false

      // 提示用户可能需要重新生成报告内容
      ElMessageBox.confirm(
        '数据范围已更新，建议重新生成报告章节内容以确保分析基于最新的数据范围。是否立即重新生成所有章节内容？',
        '提示',
        {
          confirmButtonText: '立即重新生成',
          cancelButtonText: '稍后手动生成',
          type: 'warning',
        },
      )
        .then(() => {
          // 用户选择立即重新生成
          showBatchUserOpinionDialog()
        })
        .catch(() => {
          // 用户选择稍后手动生成，不执行任何操作
        })
    } else {
      throw new Error(response.message || '更新数据范围失败')
    }
  } catch (error) {
    console.error('保存数据范围失败:', error)
    ElMessage.error(`保存失败: ${error.message || '请重试'}`)
  } finally {
    updatingDataRange.value = false
  }
}
</script>

<style scoped>
/* 修改为顶部Card模式的Tab样式 */
.content-tabs-header {
  background: transparent;
  padding: 10px 0;
  margin-bottom: 20px;
  box-shadow: var(--app-shadow-hover);
}

.content-tabs {
  border: none;
}

:deep(.el-tabs--card > .el-tabs__header) {
  border-bottom: none;
  margin-bottom: 0;
}

:deep(.el-tabs--card > .el-tabs__header .el-tabs__nav) {
  border: none;
}

:deep(.el-tabs--card > .el-tabs__header .el-tabs__item) {
  border: none;
  margin-left: 15px;
  background: transparent;
  color: var(--app-text-regular);
  font-weight: 500;
  font-size: 15px;
  transition: all 0.3s;
}

:deep(.el-tabs--card > .el-tabs__header .el-tabs__item.is-active) {
  color: var(--el-color-primary);
  border-bottom: 2px solid var(--el-color-primary);
  font-weight: bold;
}

:deep(.el-tabs--card > .el-tabs__header .el-tabs__item:hover) {
  color: var(--el-color-primary-light-3);
}

/* 为深色模式适配Tab样式 */
:global(.dark-mode) :deep(.el-tabs--card > .el-tabs__header .el-tabs__item) {
  color: var(--app-text-secondary);
  background: transparent;
  border-color: transparent;
}

:global(.dark-mode) :deep(.el-tabs--card > .el-tabs__header .el-tabs__item.is-active) {
  color: var(--el-color-primary);
  border-bottom-color: var(--el-color-primary);
}

:global(.dark-mode) :deep(.el-tabs--card > .el-tabs__header .el-tabs__item:hover) {
  color: var(--el-color-primary-light-3);
}

.report-edit-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.report-header {
  margin-bottom: 16px;
  padding: 20px 24px;
  border-radius: 4px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.06);
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(var(--el-border-color-rgb), 0.05);
  transition: all 0.3s ease;
  margin-left: 20px;
  margin-right: 20px;
}

.report-header:hover {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}

.title-section {
  display: flex;
  align-items: center;
  gap: 20px;
}

.report-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 4px;
  background: linear-gradient(135deg, var(--el-color-primary-light-5), var(--el-color-primary));
  color: white;
  font-size: 28px;
  box-shadow: 0 6px 12px rgba(var(--el-color-primary-rgb), 0.2);
  transition: all 0.3s ease;
}

.report-icon:hover {
  box-shadow: 0 8px 16px rgba(var(--el-color-primary-rgb), 0.3);
}

.title-content {
  display: flex;
  flex-direction: column;
}

.section-title {
  margin: 0 0 4px 0;
  font-size: 22px;
  color: var(--el-text-color-primary);
  font-weight: 600;
  letter-spacing: 0.5px;
  line-height: 1.4;
  display: flex;
  align-items: center;
  gap: 8px;
}

.section-title .edit-icon {
  font-size: 18px;
  opacity: 0.6;
  transition: all 0.3s ease;
  margin-left: 8px;
}

.section-title .edit-icon:hover {
  opacity: 1;
  transform: scale(1.1);
  color: var(--el-color-primary);
}

.section-description {
  margin: 0;
  color: var(--el-text-color-secondary);
  font-size: 14px;
  line-height: 1.6;
  max-width: 700px;
  opacity: 0.9;
}

.header-actions {
  display: flex;
  gap: 12px;
  align-items: center;
}

.preview-button {
  padding: 12px 24px;
  border-radius: 6px;
  font-weight: 600;
  font-size: 16px;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 10px;
  background: linear-gradient(135deg, var(--el-color-primary), var(--el-color-primary-light-3));
  color: white;
  box-shadow: 0 4px 12px rgba(var(--el-color-primary-rgb), 0.2);
  border: none;
}

.preview-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(var(--el-color-primary-rgb), 0.3);
}

/* 高级按钮样式 */
.premium-button {
  padding: 10px 18px;
  font-weight: 500;
  border-radius: 4px;
  transition: all 0.3s ease;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  border: none;
  display: flex;
  align-items: center;
  gap: 6px;
}

.premium-button:hover {
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
}

.premium-button:active {
  transform: translateY(0);
}

.generate-button {
  background: linear-gradient(135deg, var(--el-color-success), var(--el-color-success-light-3));
}

.export-button {
  background: linear-gradient(135deg, var(--el-color-primary), var(--el-color-primary-light-3));
}

.export-dropdown :deep(.el-button) {
  display: flex;
  align-items: center;
  gap: 8px;
}

.export-dropdown :deep(.el-dropdown-menu__item) {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
}

/* 报告编辑与展示阶段样式 */
.report-stage {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.report-layout {
  display: flex;
  flex: 1;
  gap: 20px;
  overflow: hidden;
  margin-bottom: 20px;
  margin-left: 20px;
  margin-right: 20px;
}

/* 左侧大纲面板 */
.outline-panel {
  width: 280px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.06);
  border-radius: 4px;
  border: 1px solid rgba(var(--el-border-color-rgb), 0.05);
  transition: all 0.3s ease;
}

.outline-panel:hover {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}

.outline-header {
  padding: 20px 24px;
  border-bottom: 1px solid rgba(var(--el-border-color-rgb), 0.1);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.outline-title {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--el-text-color-primary);
}

.outline-title .el-icon {
  font-size: 22px;
  color: var(--el-color-primary);
}

.outline-actions {
  display: flex;
  gap: 8px;
}

.outline-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
}

.outline-action-button {
  padding: 8px 16px;
  border-radius: 4px;
  font-weight: 500;
  background: linear-gradient(135deg, var(--el-color-primary), var(--el-color-primary-light-3));
  border: none;
  box-shadow: 0 2px 8px rgba(var(--el-color-primary-rgb), 0.2);
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 6px;
}

.outline-action-button:hover {
  box-shadow: 0 4px 12px rgba(var(--el-color-primary-rgb), 0.3);
  transform: translateY(-2px);
}

.outline-tree-container {
  flex: 1;
  overflow: auto;
  padding: 12px;
}

.outline-node {
  width: 100%;
  display: flex;
  align-items: center;
  min-height: 36px;
  padding: 6px 10px;
  border-radius: 4px;
  transition: all 0.2s ease;
  margin-bottom: 4px;
}

.outline-node:hover {
  background-color: rgba(var(--el-color-primary-rgb), 0.08);
}

.outline-checkbox {
  flex-shrink: 0;
  margin-right: 10px;
}

.outline-main-content {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.outline-node-label {
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  max-width: 100%;
}

.outline-right-section {
  display: flex;
  align-items: center;
  margin-left: 8px;
  flex-shrink: 0;
}

.node-status-icon {
  display: inline-flex;
  align-items: center;
  margin-right: 8px;
}

.outline-node-actions {
  opacity: 0;
  transition: opacity 0.2s ease;
}

.outline-node:hover .outline-node-actions {
  opacity: 1;
}

.outline-node .el-button {
  transition: all 0.3s ease;
}

.outline-node .el-button:hover {
  transform: scale(1.1);
}

.outline-node :deep(.el-checkbox) {
  margin-right: 0;
}

.outline-node :deep(.el-checkbox__label) {
  display: none;
}

.status-tag {
  font-size: 10px;
  border-radius: 4px;
  padding: 0 8px;
  height: 20px;
  line-height: 20px;
  font-weight: 500;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

/* 右侧内容面板 */
.content-panel {
  flex: 1;
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.content-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--app-text-secondary);
  border-radius: 4px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.06);
  padding: 40px;
  background: linear-gradient(
    rgba(var(--el-color-primary-rgb), 0.02),
    rgba(var(--el-color-primary-rgb), 0.005)
  );
  border: 1px solid rgba(var(--el-border-color-rgb), 0.05);
  transition: all 0.3s ease;
}

.section-content {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.section-editor-container {
  padding: 24px;
  border-radius: 4px;
  background: linear-gradient(
    rgba(var(--el-color-primary-rgb), 0.02),
    rgba(var(--el-color-primary-rgb), 0.005)
  );
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.06);
  border: 1px solid rgba(var(--el-border-color-rgb), 0.05);
  transition: all 0.3s ease;
}

.section-editor-container:hover {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  transform: translateY(-2px);
}

.section-editor-header {
  margin-bottom: 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 16px;
  border-bottom: 1px solid rgba(var(--el-border-color-rgb), 0.1);
}

.section-editor-header h3 {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  color: var(--el-text-color-primary);
  position: relative;
  padding-left: 16px;
}

.section-editor-header h3::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 20px;
  border-radius: 2px;
  background: linear-gradient(to bottom, var(--el-color-primary), var(--el-color-primary-light-5));
}

.section-editor {
  padding: 16px;
  border-radius: 4px;
  background-color: var(--el-bg-color);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}

.section-editor textarea {
  border-radius: 4px;
  padding: 16px;
  font-size: 15px;
  line-height: 1.6;
}

.section-preview {
  padding: 24px;
  border-radius: 4px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.06);
  margin-bottom: 0;

  border: 1px solid rgba(var(--el-border-color-rgb), 0.05);
  transition: all 0.3s ease;
}

.section-preview:hover {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  transform: translateY(-2px);
}

.preview-header {
  margin-bottom: 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 16px;
  border-bottom: 1px solid rgba(var(--el-border-color-rgb), 0.1);
}

.preview-header h3 {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  color: var(--el-text-color-primary);
  position: relative;
  padding-left: 16px;
}

.preview-header h3::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 20px;
  border-radius: 2px;
  background: linear-gradient(to bottom, var(--el-color-primary), var(--el-color-primary-light-5));
}

.preview-actions {
  display: flex;
  gap: 8px;
}

.preview-content {
  padding: 10px;
  line-height: 1.8;
  font-size: 15px;
}

.preview-content h1,
.preview-content h2,
.preview-content h3,
.preview-content h4,
.preview-content h5,
.preview-content h6 {
  margin-top: 1.5em;
  margin-bottom: 0.8em;
  font-weight: 600;
  line-height: 1.25;
  color: var(--el-text-color-primary);
}

.preview-content h1 {
  font-size: 2em;
  border-bottom: 1px solid rgba(var(--el-border-color-rgb), 0.1);
  padding-bottom: 0.3em;
}

.preview-content h2 {
  border-bottom: 1px solid rgba(var(--el-border-color-rgb), 0.1);
  padding-bottom: 0.3em;
}

.preview-content h3 {
  font-size: 1.25em;
}

.preview-content h4 {
  font-size: 1em;
}

.preview-content p {
  margin-top: 0;
  margin-bottom: 1em;
}

.preview-content strong {
  font-weight: 600;
}

.preview-content em {
  font-style: italic;
}

.preview-content blockquote {
  padding: 0.5em 1em;
  color: var(--el-text-color-secondary);
  border-left: 4px solid var(--el-color-primary-light-5);
  background-color: rgba(var(--el-color-primary-rgb), 0.03);
  margin: 16px 0;
  border-radius: 0 4px 4px 0;
}

.preview-content code {
  padding: 0.2em 0.4em;
  margin: 0;
  font-size: 0.85em;
  background-color: rgba(var(--el-color-info-rgb), 0.1);
  border-radius: 4px;
  font-family:
    ui-monospace,
    SFMono-Regular,
    SF Mono,
    Menlo,
    Consolas,
    Liberation Mono,
    monospace;
}

.preview-content pre {
  padding: 16px;
  overflow: auto;
  font-size: 0.85em;
  line-height: 1.45;
  background-color: rgba(var(--el-color-info-rgb), 0.05);
  border-radius: 4px;
  margin: 16px 0;
}

.preview-content pre code {
  padding: 0;
  margin: 0;
  background-color: transparent;
  border: 0;
  white-space: pre;
  word-break: normal;
}

.preview-content ul,
.preview-content ol {
  padding-left: 2em;
  margin-top: 0;
  margin-bottom: 1em;
}

.preview-content table {
  border-collapse: collapse;
  width: 100%;
  margin: 16px 0;
  display: block;
  overflow-x: auto;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.preview-content table th,
.preview-content table td {
  padding: 10px 16px;
  border: 1px solid rgba(var(--el-border-color-rgb), 0.1);
}

.preview-content table th {
  background-color: rgba(var(--el-color-primary-rgb), 0.05);
  font-weight: 600;
}

.preview-content table tr {
  background-color: var(--el-bg-color);
  transition: background-color 0.2s ease;
}

.preview-content table tr:nth-child(2n) {
  background-color: rgba(var(--el-fill-color-rgb), 0.3);
}

.preview-content table tr:hover {
  background-color: rgba(var(--el-color-primary-rgb), 0.03);
}

.preview-content img {
  max-width: 100%;
  margin: 16px 0;
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

.empty-analysis-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  min-height: 400px;
  padding: 20px;
}

.empty-analysis-content {
  text-align: center;
  max-width: 500px;
  margin: 0 auto;
}

.empty-placeholder {
  margin-bottom: 20px;
}

.empty-description {
  color: var(--app-text-secondary);
  margin: 15px 0;
}

.generate-action {
  margin-top: 20px;
}

.generate-btn {
  min-width: 180px;
  font-weight: 500;
  border-radius: 50px;
  box-shadow: 0 4px 15px rgba(var(--el-color-primary-rgb), 0.2);
  transition: all 0.3s ease;
  animation: pulse 2s infinite;
}

.generate-btn:hover {
  box-shadow: 0 6px 20px rgba(var(--el-color-primary-rgb), 0.3);
}

@keyframes pulse {
  0% {
    box-shadow: 0 4px 15px rgba(var(--el-color-primary-rgb), 0.2);
  }
  50% {
    box-shadow: 0 4px 25px rgba(var(--el-color-primary-rgb), 0.4);
  }
  100% {
    box-shadow: 0 4px 15px rgba(var(--el-color-primary-rgb), 0.2);
  }
}

/* 章节数据样式 */
.section-data {
  padding: 24px;
  border-radius: 4px;
  background-color: var(--el-bg-color);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  margin-top: 20px;
}

.json-data-content {
  margin-top: 16px;
}

.json-data-content .el-table {
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

.json-data-content :deep(.el-table__header) {
  background-color: rgba(var(--el-color-primary-rgb), 0.05);
}

.json-data-content :deep(.el-table__row:hover td) {
  background-color: rgba(var(--el-color-primary-rgb), 0.05);
}

.json-data-empty {
  padding: 30px;
  text-align: center;
}

/* 页面顶部添加操作按钮样式 */
.header-actions {
  display: flex;
  gap: 12px;
}

/* 全屏报告预览 */
.full-report-container {
  height: 70vh;
  overflow: auto;
  padding: 20px;
}

.report-content {
  padding: 30px;
  max-width: 900px;
  margin: 0 auto;
  background-color: var(--el-bg-color);
  border-radius: 4px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}

.report-title {
  font-size: 28px;
  font-weight: 600;
  margin-bottom: 30px;
  text-align: center;
  color: var(--el-text-color-primary);
  padding-bottom: 15px;
  border-bottom: 1px solid rgba(var(--el-border-color-rgb), 0.1);
}

.report-body {
  font-size: 15px;
  line-height: 1.8;
  color: var(--el-text-color-primary);
}

/* 美化节点样式 */
.outline-node {
  padding: 4px 0;
  border-radius: 4px;
  transition: all 0.2s ease;
}

.outline-node:hover {
  background-color: rgba(var(--el-color-primary-rgb), 0.05);
}

.outline-node-label {
  font-size: 14px;
  padding: 2px 0;
  line-height: 1.4;
  position: relative;
}

/* 美化预览区域 */
.section-preview {
  border-radius: 4px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  transition: all 0.3s ease;
}

/* 响应式适配 */
@media screen and (max-width: 768px) {
  .report-layout {
    flex-direction: column;
  }

  .outline-panel {
    width: 100%;
    max-height: 400px;
  }

  .header-actions {
    flex-direction: column;
    gap: 8px;
  }
}
.markdown-error {
  padding: 16px;
  margin: 16px 0;
  border-radius: 4px;
  background-color: rgba(var(--el-color-danger-rgb), 0.1);
  border-left: 4px solid var(--el-color-danger);
}

/* 自定义加载动画 */
.custom-loading-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 9999;
  display: flex;
  justify-content: center;
  align-items: center;
}

.loading-backdrop {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 1;
  backdrop-filter: blur(3px);
}

.loading-content {
  position: relative;
  z-index: 2;
  max-width: 90%;
  width: 500px;
  border-radius: 4px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
  padding: 32px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.loading-animation {
  width: 120px;
  height: 120px;
  margin-bottom: 24px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.loading-animation svg {
  width: 100%;
  height: 100%;
  animation: rotate 4s linear infinite;
}

.loading-animation .progress-circle {
  stroke: var(--el-color-primary);
  stroke-dasharray: 283;
  stroke-linecap: round;
  transform-origin: 50% 50%;
  animation: circle-progress 2s ease-out infinite;
}

.document-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: var(--el-color-primary);
  animation: pulse 2s infinite ease-in-out;
}

.star {
  position: absolute;
  width: 12px;
  height: 12px;
  background: var(--el-color-warning);
  clip-path: polygon(
    50% 0%,
    61% 35%,
    98% 35%,
    68% 57%,
    79% 91%,
    50% 70%,
    21% 91%,
    32% 57%,
    2% 35%,
    39% 35%
  );
  opacity: 0;
}

.star1 {
  top: 10px;
  left: 50%;
  animation: twinkle 2s infinite 0.3s;
}

.star2 {
  top: 50%;
  right: 10px;
  animation: twinkle 2s infinite 0.7s;
}

.star3 {
  top: 50%;
  left: 10px;
  animation: twinkle 2s infinite 1.1s;
}

.star4 {
  bottom: 10px;
  left: 50%;
  animation: twinkle 2s infinite 1.5s;
}

.loading-text {
  text-align: center;
}

.loading-text h3 {
  margin: 0 0 8px 0;
  font-size: 22px;
  color: var(--el-color-primary);
  font-weight: 500;
}

.loading-text p {
  margin: 0 0 24px 0;
  color: var(--el-text-color-secondary);
  font-size: 16px;
}

.loading-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-bottom: 20px;
}

.loading-dots .dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background-color: var(--el-color-primary-light-7);
  animation: dots-animation 1.4s ease-in-out infinite;
}

.loading-dots .dot:nth-child(2) {
  animation-delay: 0.2s;
}

.loading-dots .dot:nth-child(3) {
  animation-delay: 0.4s;
}

.loading-progress-status {
  width: 100%;
  border-top: 1px solid rgba(var(--el-border-color-rgb), 0.1);
  padding-top: 20px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 16px;
}

.progress-item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.progress-item .label {
  color: var(--el-text-color-secondary);
  font-size: 14px;
}

.progress-item .value {
  font-size: 14px;
  font-weight: 500;
}

.progress-item .el-icon {
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.progress-item.success .el-icon {
  color: var(--el-color-success);
}

.progress-item.error .el-icon {
  color: var(--el-color-danger);
}

@keyframes dots-animation {
  0%,
  100% {
    transform: scale(0.6);
    opacity: 0.5;
  }
  50% {
    transform: scale(1);
    opacity: 1;
  }
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

@keyframes circle-progress {
  0% {
    stroke-dashoffset: 283;
  }
  50% {
    stroke-dashoffset: 141;
  }
  100% {
    stroke-dashoffset: 283;
  }
}

@keyframes pulse {
  0%,
  100% {
    opacity: 0.6;
    transform: translate(-50%, -50%) scale(0.9);
  }
  50% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
}

@keyframes twinkle {
  0%,
  100% {
    opacity: 0;
    transform: scale(0.5);
  }
  50% {
    opacity: 1;
    transform: scale(1);
  }
}

/* 对话框提示文本样式 */
.dialog-tip {
  color: var(--el-text-color-secondary);
  line-height: 1.6;
  margin-bottom: 16px;
  font-size: 14px;
  background-color: rgba(var(--el-color-primary-rgb), 0.05);
  padding: 12px 16px;
  border-radius: 6px;
  border-left: 3px solid var(--el-color-primary);
}

.batch-operations-bar {
  padding: 12px 16px;
  background-color: rgba(var(--el-color-primary-rgb), 0.05);
  border-bottom: 1px solid rgba(var(--el-border-color-rgb), 0.1);
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: all 0.3s ease;
}

.checked-info {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--el-color-primary);
  font-size: 14px;
}

.batch-actions {
  display: flex;
  gap: 8px;
}

.edit-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--el-color-primary);
  margin-left: 5px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s ease;
  font-size: 14px;
}

.outline-node:hover .edit-icon {
  opacity: 0.8;
}

.edit-icon:hover {
  opacity: 1 !important;
  transform: scale(1.1);
}

/* 节点提示框样式 */
:deep(.node-tooltip) {
  max-width: 250px !important;
  white-space: normal !important;
  word-break: break-word;
  line-height: 1.5;
}

/* 添加一键生成报告按钮样式 */
.generate-all-button-container {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px;
  border-top: 1px solid var(--el-border-color-lighter);
}

.generate-all-button,
.clear-all-button {
  width: 100%;
  margin-left: 0px;
}

.button-description {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
  margin-top: 4px;
}

/* 删除批量操作栏相关样式 */

/* 添加删除图标样式 */
.delete-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--el-color-danger);
  margin-left: 8px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s ease;
  font-size: 14px;
}

.outline-node:hover .delete-icon {
  opacity: 0.8;
}

.delete-icon:hover {
  opacity: 1 !important;
  transform: scale(1.1);
}

/* 添加搜索框容器样式 */
.outline-search-container {
  padding: 12px 16px;
  border-bottom: 1px solid rgba(var(--el-border-color-rgb), 0.1);
}

.outline-search-container .el-input {
  font-size: 14px;
}

.editor-actions {
  display: flex;
  gap: 10px;
  align-items: center;
}

.section-editor-header {
  margin-bottom: 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 16px;
  border-bottom: 1px solid rgba(var(--el-border-color-rgb), 0.1);
}

.report-info-form {
  padding: 20px;
  background-color: var(--el-bg-color);
  border-radius: 4px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}

.report-info-form .el-form-item {
  margin-bottom: 20px;
}

.report-info-form .el-form-item label {
  font-weight: 600;
}

.report-info-form .el-input,
.report-info-form .el-textarea {
  width: 100%;
}

.report-info-form .el-button {
  width: 100%;
}

/* 数据范围按钮样式 */
.data-range-button {
  padding: 12px 24px;
  border-radius: 6px;
  font-weight: 600;
  font-size: 16px;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 10px;
  background: linear-gradient(135deg, var(--el-color-warning), var(--el-color-warning-light-3));
  color: white;
  box-shadow: 0 4px 12px rgba(var(--el-color-warning-rgb), 0.2);
  border: none;
}

.data-range-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(var(--el-color-warning-rgb), 0.3);
}

/* 数据范围对话框样式 */
.data-filter-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.filter-description {
  margin-bottom: 20px;
}

.filter-form-title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 20px;
  font-size: 18px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.filter-conditions {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.filter-condition-item {
  background-color: rgba(var(--el-color-primary-rgb), 0.02);
  border-radius: 6px;
  padding: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;
}

.filter-condition-item:hover {
  background-color: rgba(var(--el-color-primary-rgb), 0.05);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

.condition-row {
  display: flex;
  gap: 10px;
  align-items: center;
}

.condition-field {
  width: 30%;
}

.condition-operator {
  width: 20%;
}

.condition-value {
  flex: 1;
}

.condition-remove-btn {
  flex-shrink: 0;
}

.add-condition {
  margin-top: 10px;
  display: flex;
  justify-content: center;
}

.add-condition-btn {
  width: 200px;
}

.filter-preview {
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px dashed var(--el-border-color);
}

.preview-title {
  margin-bottom: 12px;
  font-weight: 500;
  color: var(--el-text-color-secondary);
}

.preview-content {
  padding: 16px;
  border-radius: 6px;
  background-color: rgba(var(--el-color-info-rgb), 0.05);
}

.preview-conditions-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.preview-condition-item {
  padding: 6px 12px;
  border-radius: 4px;
  background-color: rgba(var(--el-color-primary-rgb), 0.1);
  color: var(--el-color-primary);
  font-size: 14px;
}

.condition-separator {
  color: var(--el-text-color-secondary);
  font-weight: 500;
}

/* 深色模式适配 */
:global(.dark-mode) .filter-condition-item {
  background-color: rgba(255, 255, 255, 0.03);
}

:global(.dark-mode) .filter-condition-item:hover {
  background-color: rgba(255, 255, 255, 0.05);
}

:global(.dark-mode) .preview-content {
  background-color: rgba(255, 255, 255, 0.03);
}

:global(.dark-mode) .preview-condition-item {
  background-color: rgba(var(--el-color-primary-rgb), 0.2);
}

:global(.dark-mode) .data-range-button {
  background: linear-gradient(135deg, var(--el-color-warning-dark-2), var(--el-color-warning));
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

:global(.dark-mode) .filter-form-title {
  color: var(--el-text-color-primary);
}

:global(.dark-mode) .filter-description .el-alert {
  background-color: rgba(var(--el-color-info-rgb), 0.1);
  color: var(--el-text-color-regular);
}
</style>
